home *** CD-ROM | disk | FTP | other *** search
/ Aminet 19 / Aminet 19 (1997)(GTI - Schatztruhe)[!][Jun 1997].iso / Aminet / comm / net / ARemote1_00B.lha / ARemote / source / divert.c < prev    next >
C/C++ Source or Header  |  1997-04-27  |  24KB  |  785 lines

  1. #include <string.h>
  2. #include <stdarg.h>
  3. #include <exec/libraries.h>
  4. #include <exec/memory.h>
  5. #include <libraries/commodities.h>
  6. #include <libraries/gadtools.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <dos/dos.h>
  9. #include <clib/exec_protos.h>
  10. #include <clib/alib_protos.h>
  11. #include <clib/alib_stdio_protos.h>
  12. #include <clib/commodities_protos.h>
  13. #include <intuition/intuition.h>
  14. #include <devices/inputevent.h>
  15. #include <clib/AMarquee_protos.h>
  16. #include <pragmas/AMarquee_pragmas.h>
  17. #include <exec/types.h>
  18. #include <hardware/cia.h>
  19.  
  20. #include "ARemote_temp_aux.h"
  21.  
  22. #define CIAA 0xBFE001
  23.  
  24. #define AREMOTE_NAME "ARemote v1.00B"
  25.  
  26. const char version[] = "$VER: ARemote 1.00B";
  27.  
  28. #define DEFAULT_AREMOTE_PASSWORD  "ARemote"
  29. #define DEFAULT_AREMOTE_PORT      20000
  30. #define DEFAULT_AREMOTE_TOGGLEKEY "lcommand shift x"
  31. #define DEFAULT_AREMOTE_POPKEY    "lcommand y"
  32.  
  33. #define EVENT_TOGGLEKEY  1
  34. #define EVENT_SHOWWINDOW 2
  35.  
  36. #define UNLESS(x) if(!(x))
  37.  
  38. int main(int, char **);
  39. void ProcessMsg(struct MsgPort * broker_mp);
  40. void CxFunction(CxMsg *, CxObj *);
  41.  
  42. char * connectTo = NULL;
  43. int connectToPort;
  44. char * connectToPassword = NULL;
  45. char * acceptFrom  = NULL;
  46. int acceptFromPort;
  47. char * acceptFromPassword = NULL;
  48. BOOL BConnectOnStartup;
  49. BOOL BXmitCue;
  50. char * toggleKey = NULL;
  51. char * popKey = NULL;
  52.  
  53. /* Internal state info */
  54. BOOL BEnabled              = TRUE;
  55. BOOL BConnectOkay          = FALSE; 
  56. BOOL BWindowOpen           = FALSE;
  57. BOOL BGUINeedsUpdate       = FALSE;
  58. BOOL BSessionIsHostSession = FALSE;
  59. BOOL BXmitting             = FALSE;  /* True iff we are diverting all input to the TCP stream */
  60. BOOL BStartedFromWB        = FALSE;
  61.  
  62. struct QSession * session     = NULL;
  63. struct Library * AMarqueeBase = NULL, * CxBase        = NULL, * IconBase = NULL,
  64.                * GadToolsBase = NULL, * GfxBase  = NULL,
  65.                * UtilityBase  = NULL, * DiskFontBase  = NULL;
  66. struct Task * mainTask;
  67.  
  68. struct MsgPort * event_mp;
  69. CxObj * cxBroker = NULL, * cxFilter = NULL, * cxCustom = NULL, * cxSender = NULL, * cxDrain1 = NULL, * cxDrain2 = NULL, * cxPopFilter = NULL, * cxPopSender = NULL, * cxPopDrain = NULL;
  70.  
  71. ULONG winRequests;
  72.  
  73. struct NewBroker newbroker =
  74.   NB_VERSION,
  75.   "ARemote",
  76.   "ARemote",
  77.   "Remote-control your Amiga",
  78.   NBU_UNIQUE | NBU_NOTIFY,
  79.   COF_SHOW_HIDE, 0, 0, 0
  80. };
  81.  
  82. int MakeReq(char *sTitle, char *sText, char *sGadgets)
  83. {
  84.     struct EasyStruct myreq;
  85.     int nResult;
  86.  
  87.     UNLESS(sTitle)   sTitle   = "ARemote Message";
  88.     UNLESS(sText)    sText    = "Check this out!";
  89.     UNLESS(sGadgets) sGadgets = "OK";
  90.  
  91.     myreq.es_TextFormat   = sText;
  92.     myreq.es_Title        = sTitle;
  93.     myreq.es_GadgetFormat = sGadgets;
  94.  
  95.     if (IntuitionBase) nResult = EasyRequest(NULL, &myreq, NULL, NULL, NULL);
  96.                   else printf("Notice: [%s] [%s]\n",sTitle, sText);
  97.        
  98.     return(nResult);
  99. }
  100.  
  101.  
  102. /* does dynamic allocating and freeing of char strings */
  103. /* The old value will not be freed unless a new one could be allocated. */
  104. /* (or no new value was requested) */
  105. char * SetString(char * oldString, char * newVal)
  106. {
  107.   char * newString;
  108.     
  109.   if (newVal)
  110.   {
  111.     if (newString = AllocVec(strlen(newVal)+1, MEMF_ANY))
  112.     {
  113.       strcpy(newString, newVal);
  114.       if (oldString) FreeVec(oldString);
  115.       return(newString);
  116.     }
  117.     else 
  118.     {
  119.       DisplayBeep(NULL);
  120.       return(oldString);
  121.     }
  122.   }
  123.   else if (oldString) FreeVec(oldString);
  124.   
  125.   return(NULL);
  126. }
  127.  
  128. void StatMsg(char * msg)
  129. {
  130.   static char retain[200] = "ARemote Ready.";
  131.   
  132.   if (msg) strncpy(retain, msg, sizeof(retain));
  133.   if (BWindowOpen) SetWindowTitles(ARemoteWnd, retain, (char *)~0);
  134. }
  135.  
  136. /* Makes pcString lower case */
  137. char * ToLower(char * pcString)
  138. {
  139.     char * pcTemp = pcString;
  140.     
  141.     while(*pcTemp) 
  142.     {
  143.         if ((*pcTemp >= 'A')&&(*pcTemp <= 'Z'))
  144.             *pcTemp += 'a'-'A';
  145.         pcTemp++;
  146.     }
  147.     return(pcString);
  148. }
  149.  
  150. void edebug(int i)
  151. {
  152.   int a = *((int *)i);
  153. }
  154.  
  155. #define UPDATEMENUFLAG(item, variable, flag) {if (variable) item->Flags |= flag; else item->Flags &= ~(flag);}
  156. void UpdateGUIFromState(void)
  157. {
  158.   if (BWindowOpen)
  159.   {
  160.     struct Menu *currentMenu = ARemoteMenus;  /* Project Menu */
  161.     struct MenuItem *currentItem;
  162.  
  163.     /* Go through all gadgets and menu items, set them to the correct state */
  164.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ConnectToString],   ARemoteWnd, NULL, GTST_String, connectTo,      TAG_END);
  165.     GT_SetGadgetAttrs(ARemoteGadgets[GD_AcceptFromString],  ARemoteWnd, NULL, GTST_String, acceptFrom,     TAG_END);
  166.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ConnectToPortInt],  ARemoteWnd, NULL, GTIN_Number, connectToPort,  TAG_END);
  167.     GT_SetGadgetAttrs(ARemoteGadgets[GD_AcceptFromPortInt], ARemoteWnd, NULL, GTIN_Number, acceptFromPort, TAG_END);
  168.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ToggleString],      ARemoteWnd, NULL, GTST_String, toggleKey,      TAG_END);
  169.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ConnectToPasswordString],  ARemoteWnd, NULL, GTST_String, connectToPassword,  TAG_END);
  170.     GT_SetGadgetAttrs(ARemoteGadgets[GD_AcceptFromPasswordString], ARemoteWnd, NULL, GTST_String, acceptFromPassword, TAG_END);
  171.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ConnectOnStartupCheckbox], ARemoteWnd, NULL, GTCB_Checked, BConnectOnStartup, TAG_END);
  172.     GT_SetGadgetAttrs(ARemoteGadgets[GD_ConnectButton],    ARemoteWnd, NULL, GA_Disabled, BConnectOkay, TAG_END);
  173.     GT_SetGadgetAttrs(ARemoteGadgets[GD_DisconnectButton], ARemoteWnd, NULL, GA_Disabled, !BConnectOkay, TAG_END);
  174.     GT_SetGadgetAttrs(ARemoteGadgets[GD_XmitCueCheckbox],  ARemoteWnd, NULL, GTCB_Checked, BXmitCue, TAG_END);
  175.     GT_SetGadgetAttrs(ARemoteGadgets[GD_PopupHotkeyString],ARemoteWnd, NULL, GTST_String, popKey, TAG_END);
  176.     
  177.     ClearMenuStrip(ARemoteWnd);
  178.      currentItem = currentMenu->FirstItem;  /* About... */
  179.      currentItem = currentItem->NextItem;  /* Bar */
  180.      currentItem = currentItem->NextItem;  /* Enabled */
  181.      UPDATEMENUFLAG(currentItem, BEnabled, CHECKED);
  182.  
  183.      currentItem = currentItem->NextItem;   /* Save Settings */
  184.      UPDATEMENUFLAG(currentItem, FALSE, ITEMENABLED);
  185.     ResetMenuStrip(ARemoteWnd, ARemoteMenus);
  186.   }
  187.   BGUINeedsUpdate = FALSE;
  188. }
  189.  
  190. /* return TRUE iff the string represents the boolean value true */
  191. BOOL ParseBool(char * string)
  192. {
  193.   char temp[100];
  194.   
  195.   strncpy(temp,string,sizeof(temp));
  196.   temp[99]=0;
  197.   
  198.   ToLower(temp);
  199.   
  200.   return(
  201.     (*temp=='\0')              ||  /* then it's just KEYWORD, so yes, right? */
  202.     (strcmp("true",temp) == 0) ||
  203.     (strcmp("yes",temp)  == 0) ||
  204.     (strcmp("1",temp)    == 0));   /* Anyone who specifies 1 for true is a weenie! */
  205. }
  206.  
  207. void StartTransmitting(void)
  208. {
  209.   if (BXmitting) return;  /* we're already there */
  210.   
  211.   if (BConnectOkay) 
  212.   {
  213.     char szTemp[300];
  214.     
  215.     strcpy(szTemp, "[");
  216.     strncat(szTemp, toggleKey, sizeof(szTemp));
  217.     strncat(szTemp, "] to stop.", sizeof(szTemp));
  218.     StatMsg(szTemp);
  219.     
  220.     AttachCxObj(cxBroker, cxCustom);
  221.     AttachCxObj(cxBroker, cxDrain1);
  222.     BXmitting = TRUE;
  223.   }
  224.   else
  225.   {
  226.     DisplayBeep(NULL);
  227.     StatMsg("Can't transmit: not connected!");
  228.   }
  229. }
  230.  
  231. void StopTransmitting(void)
  232. {
  233.   if (BXmitting) 
  234.   {
  235.     StatMsg("Transmission stopped.");
  236.     RemoveCxObj(cxCustom);
  237.     RemoveCxObj(cxDrain1);
  238.   }
  239.   BXmitting = FALSE;
  240. }
  241.  
  242. void DoCloseWindow(void)
  243. {
  244.   if (BWindowOpen) 
  245.   {
  246.     CloseARemoteWindow(); 
  247.     BWindowOpen = FALSE;
  248.   } 
  249. }
  250.  
  251. void Disconnect(void)
  252. {
  253.   StopTransmitting();
  254.   if (session) 
  255.   {
  256.     QFreeSession(session);
  257.     if ((BSessionIsHostSession==FALSE)||(BConnectOkay))
  258.       StatMsg(BConnectOkay ? "Connection closed." : "Couldn't connect.");
  259.   }
  260.   session = NULL;
  261.   BConnectOkay = FALSE;
  262.   BGUINeedsUpdate = TRUE;
  263. }
  264.  
  265.  
  266. void Accept(void)
  267. {
  268.   int port = acceptFromPort;
  269.     
  270.   Disconnect();
  271.   session = QNewHostSession(acceptFrom, &port, acceptFromPassword);
  272.   BSessionIsHostSession = TRUE;
  273. }
  274.  
  275. void DoOpenWindow(void)
  276. {
  277.   if (BWindowOpen == FALSE)
  278.   {
  279.     int error;
  280.  
  281.     if (error = OpenARemoteWindow())
  282.     {
  283.       printf("Window open failed, error %i\n",error);
  284.       CloseARemoteWindow();
  285.     }
  286.     else 
  287.     {
  288.       BWindowOpen = TRUE;
  289.       UpdateGUIFromState();
  290.       StatMsg(NULL);
  291.     }
  292.   }
  293. }
  294.  
  295. void EnableCommodity(void)
  296. {
  297.   ActivateCxObj(cxBroker, 1L);
  298.   BEnabled = TRUE;
  299.   BGUINeedsUpdate = TRUE;
  300. }
  301.  
  302. void DisableCommodity(void)
  303. {
  304.   ActivateCxObj(cxBroker, 0L);
  305.   BEnabled = FALSE;
  306.   BGUINeedsUpdate = TRUE;
  307. }
  308.  
  309.  
  310. void ShowAboutBox(void)
  311. {
  312.   MakeReq(NULL, AREMOTE_NAME"\nby Jeremy Friesner\njfriesne@ucsd.edu\nCompiled: "__DATE__,"Yowza");
  313. }
  314.  
  315. void UpdateStateFromGUI(void)
  316. {  
  317.   if (BWindowOpen)
  318.   {
  319.     connectTo          = SetString(connectTo, GetString(ARemoteGadgets[GD_ConnectToString]));
  320.     acceptFrom         = SetString(acceptFrom, GetString(ARemoteGadgets[GD_AcceptFromString]));
  321.     toggleKey          = SetString(toggleKey, GetString(ARemoteGadgets[GD_ToggleString]));
  322.     connectToPassword  = SetString(connectToPassword, GetString(ARemoteGadgets[GD_ConnectToPasswordString]));
  323.     acceptFromPassword = SetString(acceptFromPassword, GetString(ARemoteGadgets[GD_AcceptFromPasswordString]));
  324.     popKey             = SetString(popKey, GetString(ARemoteGadgets[GD_PopupHotkeyString]));
  325.  
  326.     connectToPort     = GetNumber(ARemoteGadgets[GD_ConnectToPortInt]);
  327.     acceptFromPort    = GetNumber(ARemoteGadgets[GD_AcceptFromPortInt]);
  328.     BConnectOnStartup = (((ARemoteGadgets[GD_ConnectOnStartupCheckbox]->Flags)&GFLG_SELECTED) != 0);
  329.     BXmitCue          = (((ARemoteGadgets[GD_XmitCueCheckbox]->Flags)&GFLG_SELECTED) != 0);
  330.   }
  331. }
  332.  
  333. void DoChangeAccept(void)
  334. {
  335.   /* Only make a new host session if we have no session, or we have an unconnected host session */
  336.   if ((session == NULL)||((BSessionIsHostSession)&&(BConnectOkay == FALSE))) Accept();
  337. }
  338.  
  339.  
  340. /* Returns library name on failure, NULL on success */
  341. char * OpenAllLibraries(struct Library ** setLibPtr, char * libName, ULONG libVersion, ...)
  342. {
  343.   va_list vlist;
  344.   BOOL BFirst = TRUE;
  345.     
  346.   va_start(vlist, setLibPtr);
  347.   while((BFirst)||(setLibPtr = va_arg(vlist, struct Library **)))
  348.   {
  349.     libName    = va_arg(vlist, char *);
  350.     libVersion = va_arg(vlist, ULONG);
  351.     UNLESS(*setLibPtr = OpenLibrary(libName, libVersion)) return(libName);
  352.     BFirst = FALSE;
  353.   }
  354.   va_end(vlist);
  355.   return(NULL);
  356. }
  357.  
  358. void CloseAllLibraries(struct Library ** closeLib, ...)
  359. {
  360.   va_list vlist;
  361.   
  362.   if (closeLib == NULL) return;
  363.   if (*closeLib) 
  364.   {
  365.     CloseLibrary(*closeLib);
  366.     *closeLib = NULL;
  367.   }
  368.   
  369.   va_start(vlist, closeLib);
  370.   while(closeLib = va_arg(vlist, struct Library **)) 
  371.   {
  372.     if (*closeLib) 
  373.     {
  374.       CloseLibrary(*closeLib);
  375.       *closeLib = NULL;
  376.     }
  377.   }
  378.   va_end(vlist);
  379. }
  380.  
  381. /* Allocates default strings, does default settings */
  382. BOOL CreateDefaultState(UBYTE ** ttypes)
  383. {
  384.   UNLESS((connectTo          = SetString(NULL, ArgString(ttypes, "CONNECTTO", ""))) &&
  385.          (connectToPassword  = SetString(NULL, ArgString(ttypes, "CONNECTTOPASSWORD", DEFAULT_AREMOTE_PASSWORD))) &&
  386.          (acceptFrom         = SetString(NULL, ArgString(ttypes, "ACCEPTFROM", ""))) &&
  387.          (acceptFromPassword = SetString(NULL, ArgString(ttypes, "ACCEPTFROMPASSWORD", DEFAULT_AREMOTE_PASSWORD))) &&
  388.          (toggleKey          = SetString(NULL, ArgString(ttypes, "TOGGLEKEY", DEFAULT_AREMOTE_TOGGLEKEY))) && 
  389.          (popKey             = SetString(NULL, ArgString(ttypes, "CX_POPKEY", DEFAULT_AREMOTE_POPKEY)))) return(FALSE);
  390.  
  391.   BXmitCue = ParseBool(ArgString(ttypes, "FLASHLED", "FALSE"));
  392.   BConnectOnStartup = ParseBool(ArgString(ttypes, "CONNECTONSTARTUP", "FALSE"));
  393.   connectToPort  = ArgInt(ttypes, "CONNECTTOPORT", DEFAULT_AREMOTE_PORT);
  394.   acceptFromPort = ArgInt(ttypes, "ACCEPTFROMPORT", DEFAULT_AREMOTE_PORT);
  395.     
  396.   /* disable myself? */
  397.   if (ParseBool(ArgString(ttypes, "ENABLED", "TRUE")) == FALSE) Signal(FindTask(NULL), SIGBREAKF_CTRL_D);
  398.   
  399.   /* open window? */
  400.   if (ParseBool(ArgString(ttypes, "CX_POPUP", "TRUE"))) Signal(FindTask(NULL), SIGBREAKF_CTRL_F);
  401.   
  402.   return(TRUE);
  403. }
  404.  
  405. /* Frees all setting strings */
  406. void FreeState()
  407. {
  408.   connectTo          = SetString(connectTo,          NULL);
  409.   connectToPassword  = SetString(connectToPassword,  NULL);
  410.   acceptFrom         = SetString(acceptFrom,         NULL);
  411.   acceptFromPassword = SetString(acceptFromPassword, NULL);
  412.   toggleKey          = SetString(toggleKey,          NULL);
  413.   popKey             = SetString(popKey,             NULL);
  414. }
  415.  
  416. void wbmain(struct WBStartup *wbargv)
  417. {    
  418.   BStartedFromWB = TRUE;
  419.   main(0,wbargv);
  420. }
  421.  
  422. int main(int argc, char ** argv)
  423. {
  424.   UBYTE ** ttypes;
  425.   CxMsg * msg;
  426.   char * errorLib;
  427.     
  428.   mainTask = FindTask(NULL);
  429.  
  430.   if ((BStartedFromWB == FALSE)&&(argc>=2)&&(*argv[1]=='?'))
  431.   {
  432.     printf("Usage: ARemote CONNECTTO/K,CONNECTTOPASSWORD/K,CONNECTTOPORT/K/N,\n"
  433.            "               ACCEPTFROM/K,ACCEPTFROMPASSWORD/K,ACCEPTFROMPORT/K/N,\n"
  434.            "               TOGGLEKEY/K,CX_POPKEY/K,CX_POPUP/K,CX_PRIORITY/K/N\n"
  435.            "               FLASHLED/K,CONNECTONSTARTUP/K,ENABLED/K,ALLOWMULTIPLE/K\n");
  436.     exit(5);
  437.   }  
  438.  
  439.   if (errorLib = OpenAllLibraries(
  440.    &AMarqueeBase,  "amarquee.library",    43L,
  441.    &CxBase,        "commodities.library", 37L,
  442.    &IconBase,      "icon.library",        36L,
  443.    &GadToolsBase,  "gadtools.library",    37L,
  444.    &IntuitionBase, "intuition.library",   37L,
  445.    &GfxBase,       "graphics.library",    37L,
  446.    &UtilityBase,   "utility.library",     37L,
  447.    &DiskFontBase,  "diskfont.library",    38L,  NULL))
  448.   {
  449.     char temp[300];
  450.     
  451.     sprintf(temp, "Error: Couldn't open library [%s]",errorLib);
  452.     MakeReq(NULL,temp,NULL);
  453.   }
  454.   else
  455.   {
  456.     struct MsgPort * broker_mp;
  457.  
  458.     if (SetupScreen()) MakeReq(NULL, "Couldn't lock screen!", NULL);
  459.     else
  460.     {
  461.       int got_to = 0;
  462.       
  463.       if (event_mp = CreateMsgPort())
  464.       {
  465.         got_to = 1;
  466.         
  467.         if (broker_mp = CreateMsgPort())
  468.         { 
  469.           got_to = 2;
  470.           newbroker.nb_Port = broker_mp;
  471.         
  472.           ttypes = ArgArrayInit(argc, argv);
  473.           newbroker.nb_Pri = (BYTE) ArgInt(ttypes, "CX_PRIORITY", 127);
  474.           if (ParseBool(ArgString(ttypes, "ALLOWMULTIPLE", "FALSE"))) newbroker.nb_Unique &= ~(NBU_UNIQUE);
  475.           
  476.           if (CreateDefaultState(ttypes))
  477.           {
  478.             got_to = 3;
  479.             if ((cxPopFilter = CxFilter(popKey))                  &&
  480.                 (cxPopSender = CxSender(broker_mp, EVENT_SHOWWINDOW)) &&
  481.                 (cxPopDrain  = CxTranslate(NULL))                 &&
  482.                 (cxFilter = CxFilter(toggleKey))                  &&
  483.                 (cxSender = CxSender(broker_mp, EVENT_TOGGLEKEY)) &&
  484.                 (cxCustom = CxCustom(CxFunction, 0L))             &&
  485.                 (cxDrain1 = CxTranslate(NULL))                    &&
  486.                 (cxDrain2 = CxTranslate(NULL))                    &&
  487.                 (cxBroker = CxBroker(&newbroker, NULL)))
  488.             {
  489.               got_to = 4;
  490.               /* Catch the cx_popup hotkey */
  491.               AttachCxObj(cxBroker,    cxPopFilter);
  492.               AttachCxObj(cxPopFilter, cxPopSender);
  493.               AttachCxObj(cxPopFilter, cxPopDrain);
  494.               
  495.               /* Catch the toggle hotkey */
  496.               AttachCxObj(cxBroker, cxFilter);
  497.               AttachCxObj(cxFilter, cxSender);
  498.               AttachCxObj(cxFilter, cxDrain2);
  499.  
  500.               ActivateCxObj(cxBroker, 1L);
  501.  
  502.               ProcessMsg(broker_mp);
  503.             }
  504.  
  505.             /* Clean up */
  506.             if (cxPopFilter) DeleteCxObj(cxPopFilter);
  507.             if (cxPopSender) DeleteCxObj(cxPopSender);
  508.             if (cxPopDrain)  DeleteCxObj(cxPopDrain);
  509.             if (cxDrain1) DeleteCxObj(cxDrain1);
  510.             if (cxDrain2) DeleteCxObj(cxDrain2);
  511.             if (cxCustom) DeleteCxObj(cxCustom);
  512.             if (cxSender) DeleteCxObj(cxSender);
  513.             if (cxFilter) DeleteCxObj(cxFilter);
  514.             if (cxBroker) DeleteCxObj(cxBroker);
  515.             while(msg = (CxMsg *) GetMsg(broker_mp)) ReplyMsg((struct Message *)msg);
  516.           }
  517.           FreeState();
  518.           DeletePort(broker_mp);
  519.         }
  520.          
  521.         while(msg = (CxMsg *) GetMsg(event_mp)) FreeMem(msg, ((struct Message *)msg)->mn_Length);
  522.         DeletePort(event_mp);
  523.       }
  524.       ArgArrayDone();
  525.       
  526.       if (got_to != 4) 
  527.       {
  528.         char temp[300];
  529.         
  530.         sprintf(temp, "Error setting up in stage %i", got_to);
  531.         MakeReq(NULL, temp, NULL);
  532.       }
  533.     }
  534.     DoCloseWindow();
  535.     CloseDownScreen();  /* must be called even if SetupScreen() failed */
  536.   }
  537.   CloseAllLibraries(&AMarqueeBase, &CxBase, &IconBase, &GadToolsBase,
  538.                     &IntuitionBase, &GfxBase, &UtilityBase, &DiskFontBase, NULL);
  539.   return(0);
  540. }
  541.  
  542.  
  543. void Connect(void)
  544. {  
  545.   char temp[300];
  546.   
  547.   Disconnect();
  548.   session = QNewSessionAsync(connectTo, connectToPort, connectToPassword);
  549.   BSessionIsHostSession = FALSE;
  550.   
  551.   if (session)
  552.   {
  553.     strcpy(temp, "Connecting: [");
  554.     strncat(temp, connectTo, sizeof(temp));
  555.     strncat(temp, "]", sizeof(temp));
  556.     StatMsg(temp);
  557.   }
  558.   else StatMsg("Can't make connection.");
  559. }
  560.  
  561. void ChangeToggle(void)
  562. {
  563.   CxObj * newFilter;
  564.  
  565.   if (newFilter = CxFilter(toggleKey))
  566.   {
  567.     DeleteCxObj(cxFilter);
  568.     cxFilter = newFilter;
  569.     
  570.     AttachCxObj(cxFilter, cxSender);
  571.     AttachCxObj(cxFilter, cxDrain2);
  572.     AttachCxObj(cxBroker, cxFilter);    
  573.   }
  574.   else DisplayBeep(NULL);
  575. }
  576.  
  577. void ChangePopup(void)
  578. {
  579.   CxObj * newFilter;
  580.  
  581.   if (newFilter = CxFilter(popKey))
  582.   {
  583.     DeleteCxObj(cxPopFilter);
  584.     cxPopFilter = newFilter;
  585.     
  586.     AttachCxObj(cxPopFilter, cxPopSender);
  587.     AttachCxObj(cxPopFilter, cxPopDrain);
  588.     AttachCxObj(cxBroker, cxPopFilter);    
  589.   }
  590.   else DisplayBeep(NULL);
  591. }
  592.  
  593. void ToggleLED(void)
  594. {
  595.   static BOOL Bright = TRUE;
  596.   static struct CIA *cia = (struct CIA *) CIAA;
  597.   
  598.   Bright = !Bright;
  599.   
  600.   if (Bright) cia->ciapra |= CIAF_LED; else cia->ciapra &= ~(CIAF_LED);
  601. }
  602.  
  603.  
  604. void ProcessMsg(struct MsgPort * broker_mp)
  605. {
  606.   struct Message * msg;
  607.   CxMsg * cmsg;
  608.   ULONG sigrcvd;
  609.   BOOL keepGoing = TRUE;
  610.  
  611.   if (BConnectOnStartup) Connect(); else Accept();
  612.        
  613.   while(keepGoing)
  614.   {
  615.     sigrcvd = Wait((BWindowOpen ? (1L<<ARemoteWnd->UserPort->mp_SigBit) : 0L) | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F | (1L<<broker_mp->mp_SigBit) | (1L<<event_mp->mp_SigBit) | (session ? (1L<<session->qMsgPort->mp_SigBit) : 0L));
  616.     
  617.     if ((BWindowOpen)&&(sigrcvd & (1L<<ARemoteWnd->UserPort->mp_SigBit))) 
  618.     {
  619.       winRequests = 0L;
  620.       
  621.       HandleARemoteIDCMP();
  622.       
  623.       /* Check to see if HandleARemoteIDCMP() wanted the window open or closed */
  624.       if (winRequests & FLAG_UPDATE_STATE)  UpdateStateFromGUI();
  625.       if (winRequests & FLAG_CHANGE_ACCEPT) DoChangeAccept();
  626.       if (winRequests & FLAG_ABOUT)         ShowAboutBox();
  627.       if (winRequests & FLAG_CLOSE_WINDOW)  DoCloseWindow();
  628.       if (winRequests & FLAG_DISCONNECT)    Accept();
  629.       if (winRequests & FLAG_CONNECT)       Connect();
  630.       if (winRequests & FLAG_DISABLE)       DisableCommodity();
  631.       if (winRequests & FLAG_ENABLE)        EnableCommodity();
  632.       if (winRequests & FLAG_CHANGE_TOGGLE) ChangeToggle();
  633.       if (winRequests & FLAG_CHANGE_POPUP)  ChangePopup();
  634.       if (winRequests & FLAG_QUIT)          keepGoing = FALSE;
  635.     }
  636.     
  637.     while(cmsg = (CxMsg *)GetMsg(broker_mp))
  638.     {
  639.       ULONG msgid, msgtype;
  640.       
  641.       msgid = CxMsgID(cmsg);
  642.       msgtype = CxMsgType(cmsg);
  643.       
  644.       ReplyMsg((struct Message *)cmsg);
  645.  
  646.       switch(msgtype)
  647.       {
  648.         case CXM_IEVENT:
  649.           switch(msgid)
  650.           {
  651.             case EVENT_TOGGLEKEY:
  652.               if (BXmitting) StopTransmitting(); else StartTransmitting();
  653.             break;
  654.             
  655.             case EVENT_SHOWWINDOW:
  656.               DoOpenWindow();
  657.               break;
  658.               
  659.             default:
  660.               printf("Unknown event %i?\n",msgid);
  661.               break;
  662.           }
  663.           break;
  664.           
  665.         case CXM_COMMAND:
  666.           switch(msgid)
  667.           {
  668.             case CXCMD_APPEAR:    DoOpenWindow();     break;
  669.             case CXCMD_DISAPPEAR: DoCloseWindow();    break;
  670.             case CXCMD_DISABLE:   DisableCommodity(); break;
  671.             case CXCMD_ENABLE:    EnableCommodity();  break;
  672.             case CXCMD_KILL:      keepGoing = FALSE;  break;
  673.             case CXCMD_UNIQUE:    DoOpenWindow();     break;
  674.           }
  675.           break;
  676.       }
  677.     }
  678.  
  679.     /* handle incoming InputEvent messages from our custom CxObject */
  680.     {
  681.       BOOL BSent = FALSE;
  682.  
  683.       while(msg = (struct Message *)GetMsg(event_mp))
  684.       {
  685.         if ((session)&&(BConnectOkay))
  686.         {
  687.           struct InputEvent * ie = (struct InputEvent *) (((UBYTE *)msg)+sizeof(struct Message));
  688.       
  689.           /* Send a copy of the Input Event to our buddy */
  690.           if (QStreamOp(session, "e", ie, sizeof(struct InputEvent))) BSent = TRUE;
  691.         }
  692.         FreeMem(msg, msg->mn_Length);
  693.       }
  694.       if (BSent) 
  695.       { 
  696.         QGo(session, 0L);
  697.         if (BXmitCue) ToggleLED();
  698.       }
  699.     }
  700.  
  701.     if (session)
  702.     {
  703.       struct QMessage * qmsg;
  704.       
  705.       while(qmsg = (struct QMessage *)GetMsg(session->qMsgPort))
  706.       { 
  707.         if (qmsg->qm_Status == QERROR_NO_ERROR)
  708.         {
  709.           if (qmsg->qm_ID == 0) 
  710.           {
  711.             char temp[300];
  712.             char * t = qmsg->qm_Path, * u;
  713.  
  714.                  if (t == NULL) t = "(unknown)";
  715.             else if ((*t)&&(u = strchr(t+1, '/'))) t = u+1;
  716.             
  717.             strncpy(temp, "Connected: [", sizeof(temp));
  718.             strncat(temp, t, sizeof(temp));
  719.             strncat(temp, "]", sizeof(temp));
  720.             StatMsg(temp);
  721.  
  722.             BConnectOkay = TRUE;
  723.             BGUINeedsUpdate = TRUE;
  724.           }
  725.           else
  726.           {
  727.             if (qmsg->qm_DataLen == sizeof(struct InputEvent))
  728.             { 
  729.               struct InputEvent * ie = (struct InputEvent *)qmsg->qm_Data;
  730.               if ((BEnabled)&&(BXmitting == FALSE)) AddIEvents(ie);  /* Don't generate events from incoming data if we are xmitting events... we don't want a feedback loop! */
  731.             }
  732.             else printf("Error, bad data size (%i != %i)\n",qmsg->qm_DataLen, sizeof(struct InputEvent));
  733.           }
  734.         }
  735.         else
  736.         {
  737.           FreeQMessage(session, qmsg);  /* Gotta free this NOW!  Before the session is gone */
  738.           Accept();  /* Will disconnect and put up a passive session again... */
  739.           break;  /* Can't evaluate while() condition again!  session is dangling! */
  740.         }
  741.         FreeQMessage(session, qmsg);
  742.       }
  743.     }
  744.     
  745.     if (sigrcvd & SIGBREAKF_CTRL_C) {printf("CTRL-C detected.\n"); keepGoing = FALSE;}
  746.     if (sigrcvd & SIGBREAKF_CTRL_D) DisableCommodity();
  747.     if (sigrcvd & SIGBREAKF_CTRL_E) EnableCommodity();
  748.     if (sigrcvd & SIGBREAKF_CTRL_F) DoOpenWindow();
  749.  
  750.     if (BGUINeedsUpdate) UpdateGUIFromState(); 
  751.   }
  752.   
  753.   if (session) 
  754.   {
  755.     QFreeSession(session);
  756.     session = NULL;
  757.   }
  758.   
  759. }
  760.  
  761. __geta4 void CxFunction(register CxMsg * cxm, CxObj * co)
  762. {
  763.   struct InputEvent * ie;
  764.   
  765.   ie = (struct InputEvent *)CxMsgData(cxm);
  766.  
  767.   if ((ie->ie_Class == IECLASS_RAWKEY)     ||
  768.       (ie->ie_Class == IECLASS_RAWMOUSE)   ||
  769.       (ie->ie_Class == IECLASS_POINTERPOS)) 
  770.   {
  771.      /* Send a message containing a copy of this InputEvent to our program for transmission */
  772.      int bufLen = sizeof(struct Message)+sizeof(struct InputEvent);
  773.      struct Message * msg = (struct Message *)AllocMem(bufLen, MEMF_PUBLIC | MEMF_CLEAR);
  774.        
  775.      if (msg)
  776.      {
  777.        msg->mn_Node.ln_Type = NT_MESSAGE;
  778.        msg->mn_Length       = bufLen;
  779.        msg->mn_ReplyPort    = NULL;   /* No reply needed; we'll just free it */
  780.        memcpy(((UBYTE *)msg)+sizeof(struct Message), ie, sizeof(struct InputEvent));
  781.        PutMsg(event_mp, msg);
  782.      }
  783.   }
  784. }